#include "sdl.h"
#include "StringInput.h"
#include "sdl_opengl.h"
#include "sdl_ttf.h"
#include "Draw.h"
#include "Gui.h"
#include <iostream>
#include <fstream>
#include "CheckBoxInput.h"
#include "StringLabel.h"
#include "tinystr.h"
#include "tinyxml.h"
#include "ButtonInput.h"
#include "TilePicker.h"
#include <map>



#include <QtWidgets/qabstractbutton.h>

//lua stuff
extern "C" {
	#include "lua.h"
	#include "lualib.h"
	#include "lauxlib.h"
}

/* the Lua interpreter */
lua_State* L;
std::map<std::string, void(*)(void)> functions;
SDL_Event event;
SDL_Surface *background ;
SDL_Surface *tiles;
SDL_Surface *screen ;




static void build_simple_doc( )
{
	std::string name = "GameObjects/";
	Gui* gui = Gui::getInstance();
	TiXmlDocument doc;
	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
	TiXmlElement * element = new TiXmlElement( "GameObject");
	std::vector<GuiElement*>::iterator it ; 
  for (it = gui->elements.begin(); it!=gui->elements.end();it++)
				{
					if((*it)->prop!="")
					{
					TiXmlElement * prop = new TiXmlElement((*it)->prop.c_str());
					TiXmlText * value = new TiXmlText((*it)->value.c_str());
					
					prop->LinkEndChild(value);
					element->LinkEndChild(prop);
					if((*it)->prop == "Name")
					{
						name.append( (*it)->value);
					}
					}
					
				} 

	doc.LinkEndChild( decl );
	doc.LinkEndChild( element );
	name.append(".xml");
	doc.SaveFile( name.c_str() );
}

static void createObjectFromFile()
{
	//QFileDialog* fd = new QFileDialog();
	//fd->exec();
	 }
static int l_addStringLabel(lua_State* L)
{
	
	std::string prop;
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	StringLabel* sl = new StringLabel(x,y, prop);
	Gui::getInstance()->addElement(sl);
	return 0;
}

static int l_addTilePicker(lua_State* L)
{
	
	std::string prop;
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	TilePicker* sl = new TilePicker(x,y, prop, tiles);
	Gui::getInstance()->addElement(sl);
	return 0;
}

static int l_addButtonInput(lua_State* L)
{
	
	std::string prop;
	std::string func;
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	func = lua_tostring(L,4);
	
	ButtonInput* bi = new ButtonInput(x,y, prop, functions[func]);
	Gui::getInstance()->addElement(bi);
	return 0;
}

static int l_addStringInputWithLabel(lua_State* L)
{
	std::string prop;
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	printf(prop.c_str());
	StringLabel* sl = new StringLabel(x,y,prop);
	StringInput* si = new StringInput(x+125, y , prop);
	Gui::getInstance()->addElement(sl);
	Gui::getInstance()->addElement(si);
	return 00;
}


static int l_addCheckBoxInputWithLabel(lua_State* L)
{
	std::string prop;
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	StringLabel* sl = new StringLabel(x,y,prop);
	CheckBoxInput* si = new CheckBoxInput(x+125,y,prop);
	Gui::getInstance()->addElement(sl);
	Gui::getInstance()->addElement(si);
	return 0;
}

static int l_addCheckBoxInput(lua_State* L)
{
	std::string prop;
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	CheckBoxInput* cbi = new CheckBoxInput(x,y, prop);
	Gui::getInstance()->addElement(cbi);
	return 0;
}


static int l_addStringInput(lua_State *L)
{
	std::string prop = "";
	int x = 0 ;
	int y = 0 ;
	x = lua_tonumber(L, 1);
	y = lua_tonumber(L, 2);
	prop = lua_tostring(L,3);
	StringInput* si = new StringInput(x,y, prop);
	Gui* gui = Gui::getInstance();
	gui->addElement(si);
	//gui->drawElements(screen);
  //Update the screen
    
	return 1;
}

static int createGui(lua_State *L){


}




bool load_files()
{
    //Load the background image
    background = Draw::load_image( "background.png" );
    
 		SDL_FillRect( background, &background->clip_rect, SDL_MapRGB( screen->format, 0x00, 0x00, 0x00 ) );
    //Open the font
   // Draw::font = TTF_OpenFont( "DroidSerif-Regular.ttf", 28 );
    
    //If there was a problem in loading the background
    if( background == NULL )
    {
        return false;    
    }
    
    //If there was an error in loading the font
 /*   if( Draw::font == NULL )
    {
        return false;
    }
 */   
    //If everything loaded fine
    return true;    
}

void apply_surface(const int x, const int y,  SDL_Surface* source, SDL_Surface* destination,  SDL_Rect* clip  )//clip is the clip taken from the SOURCE. it has x,y,w, and h.
{
	//Holds offsets
	SDL_Rect offset;

	//Get offsets
	offset.x = x;
	offset.y = y;

	//Blit
	SDL_BlitSurface( source, clip, destination, &offset );
}

 

bool init()
{
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }
	Draw::init();
	tiles = Draw::load_image("tileset.gif");
    //Set up the screen
    screen = SDL_SetVideoMode( Draw::SCREEN_WIDTH, Draw::SCREEN_HEIGHT, Draw::SCREEN_BPP, SDL_FULLSCREEN );

    //If there was an error in setting up the screen
    if( screen == NULL )
    {
        return false;
    }

    //Initialize SDL_ttf
    if( TTF_Init() == -1 )
    {
        return false;
    }

    //Set the window caption
    SDL_WM_SetCaption( "High Score", NULL );

    //If everything initialized fine
    return true;
}

void printObjectToFile();


int main( int argc, char* args[] )
{
	
	//Quit flag
    bool quit = false;
 
    //Initialize
    if( init() == false )
    {
        return 1;
    }
	Gui* gui = Gui::getInstance();
	   //Load the files
    if( load_files() == false )
    {
        return 1;
    } 
	//^^^^^DON'T PUT ANYTHING ABOVE THIS LINE ^^^^^^^
	
	functions["build_simple_doc"] = build_simple_doc;
	/* initialize Lua */
	L = lua_open();

	/* load Lua base libraries */
	luaL_openlibs(L);

	/* register our function */ 
	
	lua_register(L, "addStringInput", l_addStringInput);
	lua_register(L,"addCheckBoxInput" , l_addCheckBoxInput);
	lua_register(L, "addStringInputWithLabel", l_addStringInputWithLabel);
	lua_register(L,"addCheckBoxInputWithLabel" , l_addCheckBoxInputWithLabel);
	lua_register(L,"addStringLabel" , l_addStringLabel);
	lua_register(L,"addButtonInput" , l_addButtonInput);
	
	lua_register(L,"addTilePicker" , l_addTilePicker);
	/* run the script */
	luaL_dofile(L, "avg.lua");
	 
	/* cleanup Lua */
	lua_close(L);
	//TilePicker* tp = new TilePicker(0,0,"test",tiles);
	//gui->addElement(tp);
	createObjectFromFile();
	gui->drawElements(screen);
 
    //While the user hasn't quit
    while( quit == false )
    {
		 
        //While there's events to handle
        while( SDL_PollEvent(&event ) )
        {
             
                //Get user input
                gui->handleInput(event);//handle input should be in some kind of gui class
                
                //If the enter key was pressed
                if( (event.type == SDL_KEYDOWN ) && (event.key.keysym.sym == SDLK_RETURN ) )
                {
                    quit = true;
                }
            }
            
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            } 

        
        //Apply the background
 		SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0x00, 0x00, 0x00 ) );
        Draw::apply_surface( 0, 0, background, screen );
        
				gui->drawElements(screen);
	
        //Update the screen
        if( SDL_Flip(screen ) == -1 )
        {
            return 1;    
        }
    }



	//build_simple_doc();
	//printObjectToFile();
	//TODO: get the string values from the boxes and write them to a file.
	return 0;

}

void printObjectToFile()
{
	std::ofstream myfile;
  myfile.open ("example.txt");
  std::vector<GuiElement*>::iterator it ;
  Gui* gui = Gui::getInstance();
  for (it = gui->elements.begin(); it!=gui->elements.end();it++)
				{
					StringInput* e = dynamic_cast<StringInput*> (*it);
					myfile<< e->getString() ;

				}
  myfile.close(); 
}